package learnJVM.ch09;

/**
 * Created by lyk on 2018-11-26.
 * Package name: learnJVM.ch09
 * Porject name: untitled1
 */


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface IBusiness {
    boolean doBusiness();
}
interface IBusiness2 {
    void doBusiness2();

}

class Business implements IBusiness, IBusiness2 {

    public boolean doBusiness() {
        System.out.println("执行业务逻辑");
        return true;
    }

    public void doBusiness2() {
        System.out.println("执行业务逻辑2");
    }



}
public class DynamicProxyDemo {

    public static void main(String[] args) {
        // 需要代理的接口，被代理类实现的多个接口都必须在这里定义
        Class[] proxyInterface = new Class[] { IBusiness.class,
                IBusiness2.class };
        // 构建AOP的Advice，这里需要传入业务类的实例
        LogInvocationHandler handler = new LogInvocationHandler(new Business());
        // 生成代理类的字节码加载器
        ClassLoader classLoader = DynamicProxyDemo.class.getClassLoader();
        // 织入器，织入代码并生成代理类
        IBusiness2 proxyBusiness = (IBusiness2) Proxy.newProxyInstance(
                classLoader, proxyInterface, handler);
        // 使用代理类的实例来调用方法。
        proxyBusiness.doBusiness2();
        ((IBusiness) proxyBusiness).doBusiness();
    }

    /**
     * 打印日志的切面
     */
    public static class LogInvocationHandler implements InvocationHandler {

        private Object target; // 目标对象

        LogInvocationHandler(Object target) {
            this.target = target;
        }

        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            // 执行原有逻辑
            Object rev = method.invoke(target, args);
            // 执行织入的日志，你可以控制哪些方法执行切入逻辑
            if (method.getName().equals("doBusiness2")) {
                System.out.println("记录日志");
            }
            return rev;
        }
    }

}